﻿using UnityEngine;
using UnityEngine.UI;

namespace IQIGame.Onigao.Framework
{
    [AddComponentMenu("UIEx/ExCanvas")]
    [RequireComponent(typeof(Canvas), typeof(GraphicRaycaster))]
    [DisallowMultipleComponent]
    public class ExCanvas : ExMono
    {
        public ExCanvas()
        {
        }

        public string sortingLayerName => this.currCav.sortingLayerName;
        public int sortingLayerID => this.currCav.sortingLayerID;
        public int sortingOrder => this.currCav.sortingOrder;

        public int baseSortingOrder { get; private set; } = 0;

        private Canvas _currCav;
        public Canvas currCav
        {
            get
            {
                if (this._currCav == null) { this._currCav = GetComponent<Canvas>(); this.currCav.overrideSorting = true; }
                return this._currCav;
            }
        }

        private GraphicRaycaster _currGRaycaster;
        public GraphicRaycaster currGRaycaster
        {
            get
            {
                if (this._currGRaycaster == null) this._currGRaycaster = GetComponent<GraphicRaycaster>();
                return this._currGRaycaster;
            }
        }

        public ExCanvas SetSortOrder(string sortingLayerName, int sortingOrder, bool isInitBase = true)
        {
            if (this.currCav != null)
            {
                bool isActive = this.gameObject.activeSelf;
                if (!isActive)
                    this.SetActive(true);

                this.currCav.overrideSorting = true;
                this.currCav.sortingLayerName = sortingLayerName;
                this.currCav.sortingOrder = sortingOrder;
                if (!isActive)
                    this.SetActive(isActive);
            }
            if (isInitBase || this.baseSortingOrder == 0)
                this.baseSortingOrder = sortingOrder;

            return this;
        }

        public bool isCanAddOrderByParent = false;

        [HideInInspector] public short mAddOrderValue = 1;
        private ExCanvas _parentExCanvas = null;
        public ExCanvas parentExCanvas => this._parentExCanvas;

        private void OnTransformParentChanged()
        {
            this.UpdateSortingOrderByParentChanged();
        }

        private void UpdateSortingOrderByParentChanged()
        {
            if (!this.isCanAddOrderByParent)
                return;
            var parent = this.transform.parent;
            ExCanvas parentCavs = parent?.GetComponentInParent<ExCanvas>();
            this.ExcuteUpdateSortingOrderByParent(parentCavs);
        }

        public void UpdateSortingOrderByParent()
        {
            if (!this.isCanAddOrderByParent)
                return;
            ExCanvas cavsParent = this.gameObject.GetFirstParent<ExCanvas>();
            this.ExcuteUpdateSortingOrderByParent(cavsParent);
        }

        private void ExcuteUpdateSortingOrderByParent(ExCanvas cavsParent)
        {
            if (this._parentExCanvas != cavsParent)
            {
                this._parentExCanvas = cavsParent;
                if (cavsParent == null)
                {
                    this.SetSortOrder(this.sortingLayerName, this.baseSortingOrder, false);
                }
                else
                {
                    this.SetSortOrder(cavsParent.sortingLayerName, cavsParent.baseSortingOrder + this.mAddOrderValue, false);
                }
            }
        }
    }
}
